package com.imooc.repeatsubmit;

import com.imooc.enums.BaseEnum;
import com.imooc.error.BusinessException;
import com.imooc.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.redisson.api.RLock;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@Slf4j
@Aspect
@Component
public class RepeatSubmitAspect {

    @Pointcut("@annotation(repeatSubmit)")
    public void pointNoRepeatSubmit(RepeatSubmit repeatSubmit) {

    }

    @Around("pointNoRepeatSubmit(noRepeatSubmit)")
    public Object around(ProceedingJoinPoint joinPoint, RepeatSubmit noRepeatSubmit) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        String path = request.getServletPath();
        long lockTime = noRepeatSubmit.lockTime();
        String key = "REPEAT_SUBMIT_" + path + token;
        // 分布式锁
        RLock lock = RedisUtil.getClient().getLock(key);
        // 尝试加锁，最多等待0秒，上锁后5秒自动解锁，lockTime默认未5s，用户可以自定义
        boolean res = false;
        try {
            res = lock.tryLock(0, lockTime, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            log.error("中断异常：", e);
        }
        if (!res) {
            throw new BusinessException(BaseEnum.NO_REPEAT_SUBMIT, BaseEnum.NO_REPEAT_SUBMIT.getMsg());
        }
        return joinPoint.proceed();
    }

}
